﻿using Candy.Infrastructure;
using Candy.Model;
using System.ComponentModel;

namespace Candy.ViewModel
{
    public class CandyEditorViewModel : CandyViewModelBase
    {


        private FamiliesViewModel _familiesVm;
        public FamiliesViewModel FamiliesVm
        {
            get
            {
                return _familiesVm;
            }
            set
            {
                _familiesVm = value;
                RaisePropertyChanged("FamiliesVm");
            }
        }

        private GenesViewModel _genesVm;
        public GenesViewModel GenesVm
        {
            get
            {
                return _genesVm;
            }
            set
            {
                _genesVm = value;
                RaisePropertyChanged("GenesVm");
            }
        }

        
        
        
        
        //public GeneFamily VirtualFamilyRoot
        //{
        //    get
        //    {
        //        return DataAccess.Instance.VirtualFamilyRoot;
        //    }
        //}

        //public IEnumerable<GeneFamily> Families
        //{
        //    get
        //    {
        //        var ret = new List<GeneFamily> {
        //            DataAccess.Instance.VirtualFamilyRoot
        //        };
        //        return ret;
        //    }
        //}





        //GeneFamily _selectedFam;
        //public GeneFamily SelectedFamily
        //{
        //    get
        //    {
        //        return _selectedFam;
        //    }
        //    set
        //    {

        //        _selectedFam = value;
        //        _genesValid = false;
        //        RaisePropertyChanged("SelectedFamily");
        //        RaisePropertyChanged("Genes");
        //        RaisePropertyChanged("Alignments");
        //        RaisePropertyChanged("HasFamilySelected");
        //    }
        //}

        //private bool _hasFamilySelected;
        //public bool HasFamilySelected
        //{
        //    get
        //    {
        //        return _selectedFam != null && _selectedFam.Name != "Root";
        //    }

        //}


        //public ObservableCollectionEx<Phylogeny> Alignments
        //{

        //    get
        //    {
        //        if (SelectedFamily != null)
        //        {

        //            return SelectedFamily.Alignments;

        //        }
        //        else
        //            return null;
        //    }
        //}

        //private Phylogeny _selectedAlignment;
        //public Phylogeny SelectedAlignment
        //{
        //    get
        //    {
        //        return _selectedAlignment;
        //    }
        //    set
        //    {
        //        if (_selectedAlignment != value)
        //        {
        //            _selectedAlignment = value;
        //            RaisePropertyChanged("SelectedAlignment");

        //        }
        //    }

        //}

        //Gene _selectedGene;
        //public Gene SelectedGene
        //{
        //    get
        //    {
        //        return _selectedGene;
        //    }
        //    set
        //    {
        //        _selectedGene = value;
        //        //if (_selectedGene != null)
        //        //{
        //        //    ExpressionViewModel.SetGene(_selectedGene.UId);
        //        //    SnpDataViewModel.SetGene(_selectedGene.UId);
        //        //}
        //        //else
        //        //{
        //        //    ExpressionViewModel.SetGene(Guid.Empty);
        //        //    SnpDataViewModel.SetGene(Guid.Empty);
        //        //}
        //        RaisePropertyChanged("SelectedGene");
        //        RaisePropertyChanged("HasGeneSelected");
        //    }
        //}

        //private bool _;
        //public bool HasGeneSelected
        //{
        //    get
        //    {
        //        return _selectedGene != null;
        //    }
        //}

        void _selectedGene_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //if (e.PropertyName == "GeneIdentifiere")
            //{
            //    Guid? de = FindOtherGeneById(VirtualFamilyRoot, (sender as Gene).GeneIdentifiere, (sender as Gene).UId);
            //    if (de != null)
            //        MessageBox.Show("Double entry for gene identifiere '" + (sender as Gene).GeneIdentifiere + "' found! Please correct your entry!", "Double Entry", MessageBoxButton.OK);
            //}
            //else if (e.PropertyName == "Name")
            //{
            //    Guid? de = FindOtherGeneByName(VirtualFamilyRoot, (sender as Gene).Name, (sender as Gene).UId);
            //    if (de != null)
            //        MessageBox.Show("Double entry for gene name '" + (sender as Gene).Name + "' found! Please correct your entry!", "Double Entry", MessageBoxButton.OK);
            //}
        }

        //private Guid? FindOtherGeneById(GeneFamily fam, string identifiere, Guid except)
        //{
        //    var ret = fam.Genes.FirstOrDefault(x => x.GeneIdentifiere == identifiere && x.UId != except);
        //    if (ret != null)
        //        return ret.UId;
        //    foreach (var item in fam.SubFamilies)
        //    {
        //        var x = FindOtherGeneById(item, identifiere, except);
        //        if (x != null)
        //            return x;
        //    }
        //    return null;
        //}

        //private Guid? FindOtherGeneByName(GeneFamily fam, string name, Guid except)
        //{
        //    var ret = fam.Genes.FirstOrDefault(x => x.Name == name && x.UId != except);
        //    if (ret != null)
        //        return ret.UId;
        //    foreach (var item in fam.SubFamilies)
        //    {
        //        var x = FindOtherGeneByName(item, name, except);
        //        if (x != null)
        //            return x;
        //    }
        //    return null;
        //}

        //public ObservableCollectionEx<Tag> Tags
        //{
        //    get
        //    {

        //        return DataAccess.Instance.Tags;

        //    }
        //}


        //public ObservableCollectionEx<Pathway> Pathways
        //{
        //    get
        //    {
        //        return DataAccess.Instance.Pathways;
        //    }
        //}

        //private ObservableCollection<Gene> _genes;
        //private bool _genesValid = false;
        //public IEnumerable<Gene> Genes
        //{
        //    get
        //    {
        //        if (_genes != null)
        //        {
        //            foreach (var item in _genes)
        //            {
        //                item.PropertyChanged -= new PropertyChangedEventHandler(_selectedGene_PropertyChanged);
        //            }
        //            List<GeneFamily> fams = new List<GeneFamily>();
        //            foreach (var item in _genes)
        //            {
        //                if (!fams.Contains(item.GeneFamily))
        //                    fams.Add(item.GeneFamily);
        //            }
        //            foreach (var item in fams)
        //            {
        //                item.Genes.CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Genes_CollectionChanged);
        //            }
        //        }
        //        if (_selectedFam != null)
        //        {
        //            if (!_genesValid)
        //            {
        //                _genes = GetSubGenes(_selectedFam).ToObservableCollection();
        //                _genesValid = true;
        //            }
        //            if (_genes != null)
        //            {
        //                List<GeneFamily> fams = new List<GeneFamily>();
        //                fams.Add(_selectedFam);
        //                foreach (var item in _genes)
        //                {
        //                    if (!fams.Contains(item.GeneFamily))
        //                        fams.Add(item.GeneFamily);
        //                }
        //                foreach (var item in fams)
        //                {
        //                    item.Genes.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Genes_CollectionChanged);
        //                }
        //            }
        //            foreach (var item in _genes)
        //            {
        //                item.PropertyChanged += new PropertyChangedEventHandler(_selectedGene_PropertyChanged);
        //            }
        //            return _genes;

        //        }
        //        else
        //            return null;
        //    }
        //}

        //void Genes_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        //{
        //    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        //    {
        //        foreach (var item in e.NewItems)
        //        {
        //            _genes.Add((Gene)item);
        //        }
        //    }
        //    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        //    {
        //        foreach (var item in e.OldItems)
        //        {
        //            _genes.Remove((Gene)item);
        //        }
        //    }
        //    RaisePropertyChanged("Genes");
        //    SelectedFamily.RaiseCountChangeEvent();
        //}

        //private IEnumerable<Gene> GetSubGenes(GeneFamily gf)
        //{
        //    List<Gene> ret = new List<Gene>();
        //    foreach (var item in gf.SubFamilies)
        //    {
        //        ret.AddRange(GetSubGenes(item));
        //    }
        //    ret.AddRange(gf.Genes);
        //    var ret2 = from x in ret orderby x.Name select x;
        //    return ret2;
        //}

        //public ObservableCollection<Genotype> GenotypesFiltered
        //{
        //    get
        //    {
        //        return (from x in DataAccess.Instance.Genotypes where x.UId != Guid.Empty orderby x.Genus, x.Species, x.Variety select x).ToObservableCollection();
        //    }
        //}

        //public ObservableCollection<Database> DatabasesFiltered
        //{
        //    get
        //    {
        //        return (from x in DataAccess.Instance.Databases where x.UId != Guid.Empty orderby x.IsFishingDB, x.Name, x.Version select x).ToObservableCollection();
        //    }
        //}



        private JobManagerViewModel _jobManager;
        public JobManagerViewModel JobManager
        {
            get
            {
                return _jobManager;
            }
            private set
            {
                _jobManager = value;
                RaisePropertyChanged("JobManager");
            }
        }

        IDataService _dataService;
        INavigationService _navigationService;

        public CandyEditorViewModel(IDataService dataService, INavigationService navigationService, JobManagerViewModel jobManagerVM)
        {
            _dataService = dataService;
            _navigationService = navigationService;
            _jobManager = jobManagerVM;
            FamiliesVm = new FamiliesViewModel(_dataService, _navigationService);
            GenesVm = new GenesViewModel(_dataService, _navigationService);
            if (IsInDesignMode)
            {
                FamiliesVm.Load.Execute(null);

            }


            //  ExpressionViewModel = new ExpressionViewModel();
            // SnpDataViewModel = new SnpDataViewModel();
           // DataAccess.Instance.LoadFinished += new EventHandler(Instance_LoadFinished);
        }

        //public void AddFamily(GeneFamily parent)
        //{
        //    GeneFamily gf = new GeneFamily { Name = "New Family", UId = Guid.NewGuid(), SubFamilies = new ObservableCollectionEx<GeneFamily>(), Genes = new ObservableCollectionEx<Gene>() };
        //    if (parent.UId != Guid.Empty)
        //    {
        //        gf.ParentFamily_Fk = parent.UId;
        //        gf.Parent = parent;
        //    }
        //    parent.SubFamilies.Add(gf);
        //}

        //internal void DeleteFamily(GeneFamily geneFamily)
        //{
        //    //if (geneFamily != null)
        //    //{
        //    //    if (geneFamily != VirtualFamilyRoot)
        //    //    {
        //    //        if (MessageBoxResult.OK == MessageBox.Show(string.Format("You are about to delete '{0}' and all subfamilies.", geneFamily.Name), "Delete", MessageBoxButton.OKCancel))
        //    //        {
        //    //            if (geneFamily.Parent != null)
        //    //                geneFamily.Parent.SubFamilies.Remove(geneFamily);
        //    //            else
        //    //                VirtualFamilyRoot.SubFamilies.Remove(geneFamily);
        //    //        }
        //    //    }
        //    //    else
        //    //        MessageBox.Show("Can't delete family root", "Error", MessageBoxButton.OK);
        //    //}
        //}

        //public Gene AddGene()
        //{
        //    Gene g = new Gene
        //    {
        //        //UId = Guid.NewGuid(),
        //        //Name = "NewGene",
        //        //GeneIdentifiere = "",
        //        //GeneFamily = SelectedFamily,
        //        //Family_Fk = SelectedFamily.UId,
        //        //Genotype = DataAccess.Instance.Genotypes.SingleOrDefault(x => x.Genus == "N/A"),
        //        //Genotype_Fk = DataAccess.Instance.Genotypes.SingleOrDefault(x => x.Id.ToLower() == "n/a").UId,
        //        //Database = DataAccess.Instance.Databases.SingleOrDefault(x => x.DisplayName == "N/A"),
        //        //Database_Fk = DataAccess.Instance.Databases.SingleOrDefault(x => x.DisplayName == "N/A").UId,
        //        //EntryType = "bait",
        //        //ScientificEvidence = 1,
        //        //Tags = new ObservableCollectionEx<MappedGeneItem<Tag>>(),
        //        //Pathways = new ObservableCollectionEx<MappedGeneItem<Pathway>>(),
        //        //References = new ObservableCollectionEx<Reference>(),
        //        //Synonyms = new ObservableCollectionEx<GeneSynonym>()
        //    };
        //    SelectedFamily.Genes.Insert(0, g);
        //    //_genes.Add(g);
        //    SelectedFamily.RaiseCountChangeEvent();
        //    return g;
        //}


        //void Instance_LoadFinished(object sender, EventArgs e)
        //{
        //    RaisePropertyChanged("Families");
        //    RaisePropertyChanged("SubFamilies");
        //    RaisePropertyChanged("VirtualFamilyRoot");
        //    RaisePropertyChanged("Tags");
        //    RaisePropertyChanged("Pathways");
        //    RaisePropertyChanged("GenotypesFiltered");
        //    RaisePropertyChanged("DatabasesFiltered");
        //    //DataAccess.Instance.Genotypes.CollectionItemChanged += new EventHandler<CollectionItemChangedEventArgs<Genotype>>(Genotypes_CollectionItemChanged);
        //    //DataAccess.Instance.Databases.CollectionItemChanged += new EventHandler<CollectionItemChangedEventArgs<Database>>(Databases_CollectionItemChanged);
        //}

        //void Databases_CollectionItemChanged(object sender, CollectionItemChangedEventArgs<Database> e)
        //{
        //    if (e.Property != "DisplayName")
        //    {
        //        StringBuilder sb = new StringBuilder();
        //        if (!string.IsNullOrEmpty(e.Item.Name))
        //            sb.Append(e.Item.Name);
        //        if (!string.IsNullOrEmpty(e.Item.Version))
        //            sb.AppendFormat("({0})", e.Item.Version.Trim());
        //        e.Item.DisplayName = sb.ToString();
        //    }
        //}

        //void Genotypes_CollectionItemChanged(object sender, CollectionItemChangedEventArgs<Genotype> e)
        //{
        //    if (e.Property != "Id")
        //    {
        //        StringBuilder sb = new StringBuilder();
        //        if (!string.IsNullOrEmpty(e.Item.Genus))
        //        {
        //            sb.Append(e.Item.Genus.Substring(0, Math.Min(1, e.Item.Genus.Length)).ToUpper());
        //            if (e.Item.Genus.Length > 1)
        //                sb.Append(e.Item.Genus.Substring(1, Math.Min(2, e.Item.Genus.Length)).ToLower());
        //        }
        //        if (!string.IsNullOrEmpty(e.Item.Species))
        //        {
        //            sb.Append(e.Item.Species.Substring(0, Math.Min(1, e.Item.Species.Length)).ToUpper());
        //            if (e.Item.Species.Length > 1)
        //                sb.Append(e.Item.Species.Substring(1, 1).ToLower());
        //        }
        //        if (!string.IsNullOrEmpty(e.Item.Variety))
        //        {
        //            sb.Append(e.Item.Variety.Substring(0, Math.Min(1, e.Item.Species.Length)).ToUpper());
        //            if (e.Item.Variety.Length > 1)
        //                sb.Append(e.Item.Variety.Substring(1, 1).ToLower());
        //        }
        //        e.Item.Id = sb.ToString();
        //    }
        //}



        //internal void AddSynonym()
        //{
        //    if (SelectedGene != null)
        //    {
        //        GeneSynonym gs = new GeneSynonym();
        //        gs.UId = Guid.NewGuid();
        //        gs.Gene = SelectedGene;
        //        gs.Gene_Fk = SelectedGene.UId;
        //        gs.Name = "New Synonym";
        //        SelectedGene.Synonyms.Add(gs);
        //    }
        //}

        //internal void DeleteSynonym(GeneSynonym gs)
        //{
        //    if (SelectedGene != null)
        //    {
        //        SelectedGene.Synonyms.Remove(gs);
        //    }
        //}

        //internal void AddReference()
        //{

        //    Reference r = new Reference();
        //    r.Gene = SelectedGene;
        //    r.Gene_Fk = SelectedGene.UId;
        //    r.UId = Guid.NewGuid();
        //    r.Title = "New Reference";
        //    SelectedGene.References.Add(r);
        //}

        //internal void DeleteReference(Reference r)
        //{
        //    if (SelectedGene != null && r != null)
        //    {
        //        SelectedGene.References.Remove(r);
        //    }
        //}

        //internal void AddTag(string p)
        //{
        //    //if (SelectedGene == null)
        //    //    return;
        //    //Tag t = Tags.SingleOrDefault(x => x.Name.Trim().ToLower() == p.Trim().ToLower());
        //    //if (t == null)
        //    //{
        //    //    t = new Tag { Name = p.Trim(), UId = Guid.NewGuid() };
        //    //    Tags.Add(t);
        //    //}
        //    //SelectedGene.Tags.Add(new MappedGeneItem<Tag>(SelectedGene.UId, t));
        //}

        //internal void RemoveTag(MappedGeneItem<Tag> tag)
        //{
        //    MappedGeneItem<Tag> t = SelectedGene.Tags.SingleOrDefault(x => x.Item.UId == tag.Item.UId);
        //    if (t != null)
        //        SelectedGene.Tags.Remove(t);
        //}

        //internal void AddPathway(string p)
        //{
        //    //Pathway t = Pathways.SingleOrDefault(x => x.Name.Trim().ToLower() == p.Trim().ToLower());
        //    //if (t == null)
        //    //    t = new Pathway { Name = p.Trim(), UId = Guid.NewGuid() };

        //    //Pathways.Add(t);
        //    //if (t != null && SelectedGene != null)
        //    //    SelectedGene.Pathways.Add(new MappedGeneItem<Pathway>(SelectedGene.UId, t));
        //}

        //internal void RemovePathway(MappedGeneItem<Pathway> pw)
        //{
        //    if (pw != null)
        //        SelectedGene.Pathways.Remove(pw);
        //}

        //internal void DeleteGenotype(Genotype gt)
        //{
        //    //DataAccess.Instance.Genotypes.Remove(gt);
        //    //RaisePropertyChanged("GenotypesFiltered");
        //}

        //internal void AddGenotype()
        //{
        //    //Genotype gt = new Genotype
        //    //{
        //    //    UId = Guid.NewGuid(),
        //    //    Genus = ""
        //    //};

        //    //DataAccess.Instance.Genotypes.Insert(0, gt);
        //    //RaisePropertyChanged("GenotypesFiltered");
        //}

        //internal void DeleteDatabase(Database gt)
        //{
        //    //DataAccess.Instance.Databases.Remove(gt);
        //    //RaisePropertyChanged("DatabasesFiltered");
        //}

        //internal void AddDatabase()
        //{
        //    //Database gt = new Database
        //    //{
        //    //    UId = Guid.NewGuid(),
        //    //    Name = "",
        //    //    Collection = "Other"
        //    //};

        //    //DataAccess.Instance.Databases.Insert(0, gt);
        //    //RaisePropertyChanged("DatabasesFiltered");
        //}

        //internal void DeletePathway(Pathway gt)
        //{
        //    //Pathways.Remove(gt);
        //}

        //internal void AddPathway()
        //{
        //    //Pathway pw = new Pathway { UId = Guid.NewGuid(), Name = "New Pathway" };
        //    //Pathways.Add(pw);
        //}

        //internal void DeleteCurrentGene()
        //{
        //    DeleteGene(_selectedGene);
        //    //if (_selectedGene != null)
        //    //{
        //    //    if (MessageBoxResult.OK == MessageBox.Show(string.Format("You are about to delete '{0}' and all related data.", _selectedGene.Name), "Delete", MessageBoxButton.OKCancel))
        //    //    {
        //    //        _selectedGene.GeneFamily.Genes.Remove(_selectedGene);
        //    //        //_genes.Remove(_selectedGene);
        //    //        SelectedFamily.RaiseCountChangeEvent();
        //    //    }
        //    //}
        //}

        //internal bool DeleteGene(Gene gene)
        //{
        //    if (gene != null)
        //    {
        //        if (MessageBoxResult.OK == MessageBox.Show(string.Format("You are about to delete '{0}' and all related data.", _selectedGene.Name), "Delete", MessageBoxButton.OKCancel))
        //        {
        //            GeneFamily gf = gene.GeneFamily;
        //            gf.Genes.Remove(gene);
        //            //_genes.Remove(_selectedGene);
        //            gf.RaiseCountChangeEvent();
        //            return true;
        //        }
        //        else
        //            return false;
        //    }
        //    else
        //        return false;

        //}


        //internal void Blast()
        //{
        //    //if (MessageBox.Show("Your are about to BLAST the '" + SelectedFamily.Name + "'. You will find the results in the job manager.", "BLAST", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
        //    //{

        //    //    //DataAccess.Instance.RequestFamilyBlast(SelectedFamily);
        //    //    _jobManagerVM.CreateJob.Execute(new Web.Data.BlastJobDefinitionDto()
        //    //       {
        //    //           Task = Web.Data.BlastTask.blast_fishing_dbs,
        //    //           FamilyUId = SelectedFamily.UId
        //    //       }
        //    //       );
        //    //}
        //}

        //internal void SaveFile()
        //{

        //}

        //internal void SaveFastaFile(Stream str)
        //{
        //    if (SelectedFamily.SubGeneCount < 1)
        //        MessageBox.Show("The selected family doesn't contain genes", "Error", MessageBoxButton.OK);
        //    else
        //    {

        //        //DataAccess.Instance.Client.GetFamilyFastaCompleted += new EventHandler<GetFamilyFastaCompletedEventArgs>(Client_GetFamilyFastaCompleted);
        //        //DataAccess.Instance.Client.GetFamilyFastaAsync(SelectedFamily.UId, DataAccess.Instance.Project.Name, str);
        //    }
        //}



        //void Client_GetFamilyFastaCompleted(object sender, GetFamilyFastaCompletedEventArgs e)
        //{
        //    //DataAccess.Instance.Client.GetFamilyFastaCompleted -= new EventHandler<GetFamilyFastaCompletedEventArgs>(Client_GetFamilyFastaCompleted);

        //    Stream s = e.UserState as Stream;
        //    s.Write(e.Result, 0, e.Result.Length);
        //    s.Close();
        //    s = null;
        //    MessageBox.Show("File successfully saved!");


        //    //var fsfg = new FpSaveFileDialog(new Uri("FpSaveFileDialogServerSideHandler.aspx", UriKind.Relative));
        //    //Candy.FpSaveFileDialog.FpSaveFileDialogOption bla = new FpSaveFileDialog.FpSaveFileDialogOption();
        //    //bla.ContentType = "text/plain";
        //    //bla.FileName = (e.UserState as GeneFamily).Name + ".txt";

        //    //fsfg.Save(e.Result,bla);

        //}

        //internal void DeletePhylogeny(Phylogeny ph)
        //{
        //    ph.GeneFamily.Alignments.Remove(ph);
        //}


    }
}
